package com.education.monitoring;

import com.education.mail.ThirdVelocityEmail;
import com.education.util.DataUtil;
import com.education.util.DateUtil;
import com.education.util.HtmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by zhangshijie on 2015/12/13.
 */
public abstract class BaseMonitoring {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	private static final int ERROR_FREQUENCY_TIME = 10 * 60 * 1000; //异常后的调度频率,增长基数为10分钟

	private String serviceName; //监控的服务类型

	private ThirdVelocityEmail thirdVelocityEmail;

	private String subject; //监控主题

	private int errorFrequency; //异常发送邮件频率基数

	private int retryCount; //异常时重试的次数

	private int retryTime; //异常时重试休眠时间，单位毫秒

	private String[] adminEmails;

	private Date lastTime; //最后一次的正常时间点

	protected boolean checkUrl(String htppUrl) {
		String content = HtmlUtil.getContent(htppUrl);
		if(DataUtil.isEmpty(content)) {
			return false;
		}

		return true;
	}

	/**
	 * 发送邮件
	 */
	protected void sendEmail(Date noticeTime) {
		try {
			Thread.sleep(errorFrequency++ * ERROR_FREQUENCY_TIME);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		Map<String, Object> model = new HashMap<String, Object>();
		model.put("serviceName", serviceName);
		model.put("noticeTime", DateUtil.getStringFromDate(noticeTime));
		model.put("lastTime", DateUtil.getStringFromDate(lastTime));
		thirdVelocityEmail.sendEmail(model, subject, "ServiceStopNotice.vm", adminEmails, new String[]{});
	}

	private void isRepair() {
		lastTime = new Date();
		errorFrequency = 0;
		logger.info(serviceName + " 本次监控正常，监控时间：" + DateUtil.getStringFromDate(lastTime));
	}

	/**
	 * 监控服务
	 */
	public void monitoring() {
		for (int i = 0; i < retryCount; i++) {
			if(checkHeartbeat()) {
				isRepair();
				return;
			}

			try {
				Thread.sleep(retryTime); //休眠后重试
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		Date noticeTime = new Date();
		logger.error(serviceName + " 本次监控异常，监控时间：{}", DateUtil.getStringFromDate(noticeTime));
		sendEmail(noticeTime);
	}

	/**
	 * 检测心跳
	 */
	abstract boolean checkHeartbeat();

	public void setServiceName(String serviceName) {
		this.serviceName = serviceName;
	}

	public void setAdminEmails(String[] adminEmails) {
		this.adminEmails = adminEmails;
	}

	public void setThirdVelocityEmail(ThirdVelocityEmail thirdVelocityEmail) {
		this.thirdVelocityEmail = thirdVelocityEmail;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public void setRetryCount(int retryCount) {
		this.retryCount = retryCount;
	}

	public void setRetryTime(int retryTime) {
		this.retryTime = retryTime;
	}
}
